/*!
 * jquery.range-picker.js - v 0.0.1
 * author: http://my.oschina.net/dtec
 * date: 2013-8-1 19:00
 */
(function(window,$,undefined){
	$.range_picker = function(sel,options){
		var selector = sel,
	 	picker = this,
	 	axis = null,
	 	pickers = null,
	 	selected = null,
	 	defaults = {
	 		from:0,
	 		to:'∞',
		 	ranges:[0,1000,2000,5000,10000,'∞'],
		 	axis_width:200,
		 	picker_width:8,
		 	show_seperator:true,
		 	can_switch:false,
		 	animate:false,
		 	onDrag:function(){},
		 	onSelect:function(){},
		 	beforeInit:function(){},
		 	afterInit:function(){}
		};
		picker.sel = selector;
		picker.options = options = $.extend({},defaults,options);
		var ranges = options.ranges;
		var picker_lefts = [];
		var pl_first = 0,pl_last = 0,pl_init = 0,pr_init = 0;
		var build_picker_ranges = function(){
			var width = options.axis_width;
			var left = options.picker_width/2;
			pl_first = -left;
			pl_last = options.axis_width-left;
			picker_lefts.push(pl_first);
			var len = ranges.length;
			for(var i=1;i<len-1;i++){
				picker_lefts.push(i*width/(len-1)-left);
			}
			picker_lefts.push(pl_last);
			var pleft = axis.find('.left');
			var pright = axis.find('.right');
			picker.picker_lefts = picker_lefts;
			pl_init = pleft.offset().left;
			if(options.from && options.to){
				picker.set(options.from,options.to);
			}
		};
		var build_seperator = function(){
			var width = axis.width();
			var len = ranges.length-1;
			var tpl = '<span title="{title}" style="width:0;height:100%;border-left:1px solid #CCC;position:absolute;left:{left}px;"></span>';
			for(var i=0;i<len+1;i++){
				var t = $(tpl.replace(/\{left\}/ig,i*width/len).replace(/\{title\}/ig,ranges[i]));
				if(i==0)
					t.hide();
				axis.append(t);
			}
		};
		var build_dom = function(){
			axis = $('<div class="range-picker-axis"></div>').css('width',options.axis_width);
		 	selector.html(axis);
			var left = $('<div class="range-picker left"></div>');
			var right = $('<div class="range-picker right"></div>');
			selected = $('<div class="range-selected"></div>').css('height',axis.height());
			axis.append(left).append(right).append(selected);
			pickers = axis.find('.range-picker').css('width',options.picker_width);
		};
		var get_reset_index = function(left){
			var len = picker_lefts.length;
			var width = options.axis_width/len;
			var hwidth = width / 2;
			for(var i=0;i<len;i++){
				var cur = picker_lefts[i];
				if(i==0){
					var next = picker_lefts[i+1];
					if(left>=cur && left<cur+hwidth){
						return 0;
					}else if(left>=cur+hwidth && left<next+hwidth){
						return 1;
					}else if(left<cur){
						return 0;
					}
				}else if(i==len-1){
					if(left>cur){
						return len-1;
					}
				}else{
					var next = picker_lefts[i+1];
					if(left>=cur-hwidth && left<cur+hwidth){
						return i;
					}else if(left>=cur+hwidth && left<next+hwidth){
						return i+1;
					}
				}
			}
		};
		var rebuild_from_to = function(from,to){
			if(isNaN(from)){
				if(isNaN(to)){
					return ['∞','∞'];
				}else{
					return [to,'∞'];
				}
			}else{
				if(isNaN(to)){
					return [from,'∞'];
				}else{
					return parseFloat(from)>parseFloat(to)?[to,from]:[from,to];
				}
			}
		};

		var get_lefts = function(){
			var left = axis.parent().offset().left;
			var pleft = axis.find('.left');
			var pright = axis.find('.right');
			return [pleft.offset().left - left,pright.offset().left - left];
		};
		var get_from_to_real_time = function(){
			var left = axis.parent().offset().left;
			var pleft = axis.find('.left');
			var pright = axis.find('.right');
			var ll = get_reset_index(pleft.offset().left - left);
			var rl = get_reset_index(pright.offset().left - left);
			var from = ranges[ll];
			var to = ranges[rl];
			return rebuild_from_to(from,to);
		};
		var get_from_to = function(){
			var pleft = axis.find('.left');
			var pright = axis.find('.right');
			var from = pleft.attr('title');
			var to = pright.attr('title');
			return rebuild_from_to(from,to);
		}
		var get_index_of_ranges = function(ft){
			for (var i = ranges.length - 1; i >= 0; i--) {
				if(ft+''==ranges[i]){
					return i;
				}
			};
		};
		var rebuild_selected_region = function(){
			var lefts = get_lefts();
			var width = Math.abs(lefts[0] - lefts[1]);
			var min = lefts[0]<lefts[1]?lefts[0]:lefts[1];
			selected.css({
				'width':width,
				'left':min+options.picker_width/2
			});

		};
		picker.set_by_index = function(self,index){
			var pl = picker_lefts[index];
			this.set_by_left(self,pl,options.animate);
			self.attr('title',ranges[index]);
		};
		picker.set_by_left = function(self,left,animate){
			if(!animate){
				self.css('left',left);
				rebuild_selected_region();
			}else{
				self.animate({
					'left':left
				},'fast',function(){
					rebuild_selected_region();
				});
			}
		};
		picker.set = function(from,to){
			var fi = get_index_of_ranges(from);
			var ti = get_index_of_ranges(to);
			this.set_by_index(pickers.eq(0),fi);
			this.set_by_index(pickers.eq(1),ti);
		};
		picker.init = function(){
			options.beforeInit && options.beforeInit.call(picker);
			build_dom();
			if(options.show_seperator)
				build_seperator();
			build_picker_ranges();
			pickers.on('drag',function(e,d){
				var self = $(this);
				var left = d.offsetX - pl_init - options.picker_width/2;
				if(left<pl_first || left>pl_last)
					return;
				picker.set_by_left(self,left);
				var ft = get_from_to_real_time();
				options.onChange && options.onChange.call(picker,ft);
			});
			pickers.on('dragend',function(e,d){
				var self = $(this);
				var left = d.offsetX - pl_init - options.picker_width/2;
				var index = get_reset_index(left);
				picker.set_by_index(self,index);
				self.attr("title",ranges[index]);
				var ft = get_from_to();
				options.onSelect && options.onSelect.call(picker,index,ft);
			});
			options.afterInit && options.afterInit.call(picker);
		};
		return picker;
	};
	$.fn.range_picker = function(options){
		var picker = $(this).data('range_picker');
		if($(this).length==1){
			if(!picker){
				var picker = $(this).data('range_picker');
				if(!picker){
					picker = new $.range_picker($(this),options);
					$(this).data('range_picker',picker);
					picker.init();
				}
			}
			return picker
		}
		return this.each(function(){
			var picker = $(this).data('range_picker');
			if(!picker){
				picker = new $.range_picker($(this),options);
				$(this).data('range_picker',picker);
				picker.init();
			}
		});
	};

})(window,jQuery,undefined);